package mao.genericity;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Totoro
 * @date 2020/7/7
 * @explain: 学习泛型的类型擦除。
 */
//T extends String  T被替换为String
public class Erasure<T extends String>  {
    T name;

    public void setName(T name) {
        this.name = name;
    }

    public T getName() {
        return name;
    }

    public static void main(String[] args) {
        /**
         * 泛型类Erasure<String>和Erasure是相同的类型。
         */
        Erasure<String> erasure = new Erasure<>();
        erasure.setName("bach");
        String name = erasure.getName();
        Class<? extends Erasure> aClass = erasure.getClass();
        Class<Erasure> erasureClass = Erasure.class;
        //两者是相同的。
        System.out.println(aClass.equals(erasureClass));

        ArrayList<Integer> integers = new ArrayList<>();
        integers.add(2);
        //integers.add("len") //不能添加，因为编译器检查
        Class<? extends ArrayList> iclz = integers.getClass();
        try{
            Method add = iclz.getMethod("add", Object.class); //类型擦除之后的正真的方法签名、
            add.invoke(integers,"string");
        }catch (NoSuchMethodException  e){
            e.printStackTrace();
        }catch (IllegalArgumentException e){
            e.printStackTrace();
        }catch (IllegalAccessException e){
            e.printStackTrace();
        }catch (InvocationTargetException e){
            e.printStackTrace();
        }
        for(Object o : integers){
            System.out.println(o);
        }

        //暂且不管。
        List<?>[] li3 = new ArrayList<?>[10];
        li3[1] = new ArrayList<String>();
        List<?> v = li3[1];
        Object o = v.get(0);
        System.out.println(o);
    }
}
